package com.trace.demo.controller;

import com.trace.demo.annotation.OperationLog;
import com.trace.demo.entity.LoginLog;
import com.trace.demo.repository.OperationLogRepository;
import com.trace.demo.repository.LoginLogRepository;
import com.trace.demo.common.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * 系统日志控制器
 */
@RestController
@RequestMapping("/api/system")
public class SystemLogController {

    @Autowired
    private OperationLogRepository operationLogRepository;

    @Autowired
    private LoginLogRepository loginLogRepository;

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 获取操作日志列表
     * @param page 页码
     * @param size 每页条数
     * @param search 搜索关键词
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 操作日志列表
     */
    @GetMapping("/operationLog/list")
    @OperationLog(module = "系统管理", action = "查询", description = "查询操作日志列表")
    public Result<Map<String, Object>> getOperationLogs(
            @RequestParam(value = "page", defaultValue = "1") int page,
            @RequestParam(value = "size", defaultValue = "10") int size,
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "startTime", required = false) String startTime,
            @RequestParam(value = "endTime", required = false) String endTime) {
        
        // 构建分页和排序
        PageRequest pageRequest = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "operationTime"));
        
        // 构建查询条件
        Page<com.trace.demo.entity.OperationLog> operationLogs;
        
        if (search != null && !search.isEmpty()) {
            // 如果有搜索关键词，使用模糊查询
            operationLogs = operationLogRepository.findByUserNameOrDescriptionContaining(search, pageRequest);
        } else if (startTime != null && !startTime.isEmpty() && endTime != null && !endTime.isEmpty()) {
            // 如果有时间范围，按时间范围查询
            LocalDateTime start = LocalDateTime.parse(startTime + " 00:00:00", FORMATTER);
            LocalDateTime end = LocalDateTime.parse(endTime + " 23:59:59", FORMATTER);
            operationLogs = operationLogRepository.findByOperationTimeBetween(start, end, pageRequest);
        } else {
            // 否则查询所有
            operationLogs = operationLogRepository.findAll(pageRequest);
        }
        
        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("list", operationLogs.getContent());
        result.put("totalItems", operationLogs.getTotalElements());
        result.put("totalPages", operationLogs.getTotalPages());
        
        return Result.success(result);
    }
    
    /**
     * 导出操作日志
     * @param search 搜索关键词
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 导出的Excel文件
     */
    @GetMapping("/operationLog/export")
    @OperationLog(module = "系统管理", action = "导出", description = "导出操作日志")
    public ResponseEntity<byte[]> exportOperationLogs(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "startTime", required = false) String startTime,
            @RequestParam(value = "endTime", required = false) String endTime) throws IOException {
        
        // 这里简化处理，实际应用中应该使用POI等库生成Excel
        // 这里只返回一个简单的CSV格式数据
        
        StringBuilder csv = new StringBuilder();
        csv.append("日志编号,用户名,IP地址,功能模块,操作类型,操作描述,操作结果,操作时间\n");
        
        // 构建查询条件
        Page<com.trace.demo.entity.OperationLog> operationLogs;
        PageRequest pageRequest = PageRequest.of(0, Integer.MAX_VALUE, Sort.by(Sort.Direction.DESC, "operationTime"));
        
        if (search != null && !search.isEmpty()) {
            operationLogs = operationLogRepository.findByUserNameOrDescriptionContaining(search, pageRequest);
        } else if (startTime != null && !startTime.isEmpty() && endTime != null && !endTime.isEmpty()) {
            LocalDateTime start = LocalDateTime.parse(startTime + " 00:00:00", FORMATTER);
            LocalDateTime end = LocalDateTime.parse(endTime + " 23:59:59", FORMATTER);
            operationLogs = operationLogRepository.findByOperationTimeBetween(start, end, pageRequest);
        } else {
            operationLogs = operationLogRepository.findAll(pageRequest);
        }
        
        // 构建CSV内容
        for (com.trace.demo.entity.OperationLog log : operationLogs.getContent()) {
            csv.append(log.getId()).append(",")
               .append(log.getUserName()).append(",")
               .append(log.getIpAddress()).append(",")
               .append(log.getModule()).append(",")
               .append(log.getAction()).append(",")
               .append(log.getDescription().replace(",", "，")).append(",")
               .append(log.getResult() ? "成功" : "失败").append(",")
               .append(log.getOperationTime().format(FORMATTER)).append("\n");
        }
        
        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attachment; filename=operation_logs.csv");
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        
        return new ResponseEntity<>(csv.toString().getBytes(StandardCharsets.UTF_8), headers, HttpStatus.OK);
    }
    
    /**
     * 清空操作日志
     * @return 结果
     */
    @DeleteMapping("/operationLog/clear")
    @Transactional
    @OperationLog(module = "系统管理", action = "删除", description = "清空操作日志")
    public Result<Void> clearOperationLogs() {
        operationLogRepository.deleteAllLogs();
        return Result.success();
    }
    
    /**
     * 获取登录日志列表
     * @param page 页码
     * @param size 每页条数
     * @param search 搜索关键词
     * @param status 登录状态
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 登录日志列表
     */
    @GetMapping("/loginLog/list")
    @OperationLog(module = "系统管理", action = "查询", description = "查询登录日志列表")
    public Result<Map<String, Object>> getLoginLogs(
            @RequestParam(value = "page", defaultValue = "1") int page,
            @RequestParam(value = "size", defaultValue = "10") int size,
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "status", required = false) String status,
            @RequestParam(value = "startTime", required = false) String startTime,
            @RequestParam(value = "endTime", required = false) String endTime) {
        
        // 构建分页和排序
        PageRequest pageRequest = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "loginTime"));
        
        // 构建查询条件
        Page<LoginLog> loginLogs;
        
        if (search != null && !search.isEmpty()) {
            // 如果有搜索关键词，使用模糊查询
            loginLogs = loginLogRepository.findByUserNameOrIpAddressContaining(search, pageRequest);
        } else if (status != null && !status.isEmpty()) {
            // 如果有状态，按状态查询
            loginLogs = loginLogRepository.findByStatus(status, pageRequest);
        } else if (startTime != null && !startTime.isEmpty() && endTime != null && !endTime.isEmpty()) {
            // 如果有时间范围，按时间范围查询
            LocalDateTime start = LocalDateTime.parse(startTime + " 00:00:00", FORMATTER);
            LocalDateTime end = LocalDateTime.parse(endTime + " 23:59:59", FORMATTER);
            loginLogs = loginLogRepository.findByLoginTimeBetween(start, end, pageRequest);
        } else {
            // 否则查询所有
            loginLogs = loginLogRepository.findAll(pageRequest);
        }
        
        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("list", loginLogs.getContent());
        result.put("totalItems", loginLogs.getTotalElements());
        result.put("totalPages", loginLogs.getTotalPages());
        
        return Result.success(result);
    }
    
    /**
     * 导出登录日志
     * @param search 搜索关键词
     * @param status 登录状态
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 导出的Excel文件
     */
    @GetMapping("/loginLog/export")
    @OperationLog(module = "系统管理", action = "导出", description = "导出登录日志")
    public ResponseEntity<byte[]> exportLoginLogs(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "status", required = false) String status,
            @RequestParam(value = "startTime", required = false) String startTime,
            @RequestParam(value = "endTime", required = false) String endTime) throws IOException {
        
        // 这里简化处理，实际应用中应该使用POI等库生成Excel
        // 这里只返回一个简单的CSV格式数据
        
        StringBuilder csv = new StringBuilder();
        csv.append("日志编号,用户名,IP地址,浏览器,操作系统,状态,消息,登录时间\n");
        
        // 构建查询条件
        Page<LoginLog> loginLogs;
        PageRequest pageRequest = PageRequest.of(0, Integer.MAX_VALUE, Sort.by(Sort.Direction.DESC, "loginTime"));
        
        if (search != null && !search.isEmpty()) {
            loginLogs = loginLogRepository.findByUserNameOrIpAddressContaining(search, pageRequest);
        } else if (status != null && !status.isEmpty()) {
            loginLogs = loginLogRepository.findByStatus(status, pageRequest);
        } else if (startTime != null && !startTime.isEmpty() && endTime != null && !endTime.isEmpty()) {
            LocalDateTime start = LocalDateTime.parse(startTime + " 00:00:00", FORMATTER);
            LocalDateTime end = LocalDateTime.parse(endTime + " 23:59:59", FORMATTER);
            loginLogs = loginLogRepository.findByLoginTimeBetween(start, end, pageRequest);
        } else {
            loginLogs = loginLogRepository.findAll(pageRequest);
        }
        
        // 构建CSV内容
        for (LoginLog log : loginLogs.getContent()) {
            csv.append(log.getId()).append(",")
               .append(log.getUserName()).append(",")
               .append(log.getIpAddress()).append(",")
               .append(log.getBrowser()).append(",")
               .append(log.getOs()).append(",")
               .append("success".equals(log.getStatus()) ? "成功" : "失败").append(",")
               .append(log.getMessage().replace(",", "，")).append(",")
               .append(log.getLoginTime().format(FORMATTER)).append("\n");
        }
        
        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attachment; filename=login_logs.csv");
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        
        return new ResponseEntity<>(csv.toString().getBytes(StandardCharsets.UTF_8), headers, HttpStatus.OK);
    }
    
    /**
     * 清空登录日志
     * @return 结果
     */
    @DeleteMapping("/loginLog/clear")
    @Transactional
    @OperationLog(module = "系统管理", action = "删除", description = "清空登录日志")
    public Result<Void> clearLoginLogs() {
        loginLogRepository.deleteAllLogs();
        return Result.success();
    }
} 